
/**
 @file MessageIO.h
 @brief Definición de la funcionalidad de interacción de las bibliotecas de usuario con el servicio de intercambio de mensajes.
 @date   7/12/2012
 @version v.0.9
 @author Julian Ovalle
         julianovalle@ula.ve
*/

#ifndef MESSAGEIO_H_
#define MESSAGEIO_H_

#include <sys/socket.h>
#include <netinet/in.h>
#include <list>
#include <Message.h>

using namespace std;
//#define USR_MSG_DEBUG

/**@brief Representa la interfaz de las bibliotecas de usuario con el servicio de intercambio de mensajes. */
class MessageIO {

    struct sockaddr_in _serverName; //!< Dirección del socket del servidor.
    int _s; //!< Descriptor del socket al servidor.
    Message *_response; //!< Contenedor de la respuesta a un mensaje si fué solicitada.
    list<node_t> _node_list; //!< Lista de nodos. @see node_t

    /**
      * @brief Obtiene el descriptor del socket al servidor
      */
    int getSocket();

    /**
      * @brief Obtiene la dirección del socket del servidor
      */
    struct sockaddr_in getServerName();

    /**
      * @brief Asigna la respuesta a un mensaje
      * @param *response Apuntador a un mensaje. @see Message
      */
    void setResponse(Message *response);

    /**
      * @brief Obtiene desde el servidor la respuesta a un mensaje enviado para almacenarla en *_response. @see *_response
      * @return 0 en caso de éxito. -1 en caso de error
      */
    int obtainResponse();
public:

    /*!
       @brief Inicialización de la interfaz con el servicio de intercambio de mensajes y de la lista de nodos destino.
       @return 0 en caso de exito. -1 en caso de error.
     */
    int Init();

    /*!
       @brief Finalización de la interfaz con el servicio de intercambio de mensajes.
       @return 0 en caso de exito. -1 en caso de error.
     */
    int Exit();

    /*!
       @brief Envía un mensaje de capa aplicación en unicast o broadcast.
       @param msg El mensaje a enviar.
       @return 0 en caso de exito. -1 en caso de error.
     */
    int Send(Message msg);

    /*!
       @brief Envía un mensaje de capa aplicación en multicast.
       @param msg El mensaje a enviar.
       @param destList lista de nodos destino.
       @return 0 en caso de exito. -1 en caso de error.
     */
    int SendMulticast(Message msg, list<node_t> destList);

    /*!
       @brief Envía un mensaje de capa aplicación
       @param msg El mensaje a enviar.
       @param destList lista de nodos destino. Si esta lista contiene elementos el mensaje se enviará en multicast hacia estos destinatarios. @see node_t
       @return 0 en caso de exito. -1 en caso de error.
     */
    int MessageOutput(Message* msg, list<node_t> destList);

    /*!
       @brief Solicita una nueva lista de nodos al servidor, para inicializar la propia.
       @return 0 en caso de exito. -1 en caso de error.
     */
    int requestNodeList();

    /*!
       @brief Actualiza la lista de nodos solicitando redescubrimiento al servidor
       @return 0 en caso de exito. -1 en caso de error.
     */
    int updateNodeList();

    /**
      * @brief Obtiene la lista de nodos
      */
    list<node_t> getNodeList();

    /**
      * @brief Obtiene la lista de nodos
      * @return Apuntador al mensaje respuesta. @see Message
      */
    Message* getResponse();

};


#endif /* MESSAGEIO_H_ */
